package com.hxh.generater.springBoot.springboot3_vue3.gen.crud;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.hxh.entity.*;
import com.hxh.entity.output.ApiResult;
import com.hxh.entity.po.ClassInfo;
import com.hxh.entity.po.FieldName;
import com.hxh.generater.common.GenSysMenu;
import com.hxh.generater.common.remote.RemoteUtil;
import com.hxh.generater.common.remote.SpringbootRemoteUtil;
import com.hxh.generater.springBoot.springboot3_vue3.gen.GenSb3Vue3Util;
import com.hxh.util.GenUtil;
import com.hxh.util.MysqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ProjectName: AICode
 * @Package: com.hxh.generater
 * @ClassName: GenerationController
 * @Author: HXH
 * @Description:
 * @Date: 2023/11/28 15:08
 */
@Slf4j
public class GenControllerRemote {

    /**
     * 新增某个字段获取的下拉框的controller方法后，新增菜单
     *
     * @param project
     * @param classInfo
     * @param projectTableFiledConfig
     */
    public static void processAssociationFnMenu(Project project, ClassInfo classInfo, ProjectTableFiledConfig projectTableFiledConfig) {
        String className = classInfo.getClassName();
        String classNameEntity = StringUtils.uncapitalize(className);
        String mutilDatasourceStr = GenUtil.getMutilDatasourceStrByConfig(project, classInfo, "", "/");
        String mutilDatasourcePemStr = GenUtil.getMutilDatasourceStrByConfig(project, classInfo, "", ":");
        String queryPath = "/" + mutilDatasourceStr + classNameEntity + "/page";

        String desc = "获取" + projectTableFiledConfig.getShowName() + "下拉选择列表";
        String filedName = projectTableFiledConfig.getFiledName();
        String fieldJavaName = StrUtil.toCamelCase(filedName);
        String uppercaseFirstFieldName = StrUtil.upperFirst(fieldJavaName);
        String newMenuPath = "/api/" + mutilDatasourceStr + classNameEntity + "/get" + uppercaseFirstFieldName + "Option";
        ProjectDatasource projectDatasource = project.getProjectDatasource();

        try {
            Object o = MysqlUtils.queryOneAndReturnFirstResult(projectDatasource, "select count(*) from sys_menu where path = '" + newMenuPath + "';");
            if (o == null) {
                return;
            }
            int count = Integer.parseInt(o.toString());
            if (count > 0) {
                return;
            }
            o = MysqlUtils.queryOneAndReturnFirstResult(projectDatasource, "select count(*) from sys_menu where path = '" + queryPath + "';");
            if (o == null) {
                return;
            }
            count = Integer.parseInt(o.toString());
            if (count <= 0) {
                return;
            }

            List<GenSysMenu> sb3Vue3SysMenus = MysqlUtils.executeOneQuery(projectDatasource, "select * from sys_menu where path = '" + queryPath + "';", GenSysMenu.class);
            if (sb3Vue3SysMenus.size() > 1) {
                log.warn("path：" + queryPath + "有多条结果！！！请确认菜单数据正确性");
                return;
            }
            GenSysMenu parentMenu = sb3Vue3SysMenus.get(0);
            GenSysMenu newAssociationFnMenu = new GenSysMenu();
            newAssociationFnMenu.setParentId(parentMenu.getId());
            newAssociationFnMenu.setTreePath(parentMenu.getTreePath() + "," + parentMenu.getId());
            newAssociationFnMenu.setName(desc);
            newAssociationFnMenu.setPath(newMenuPath);
            newAssociationFnMenu.setPerm(mutilDatasourcePemStr + classNameEntity + ":get" + uppercaseFirstFieldName + "Option");
            newAssociationFnMenu.setAlwaysShow("1");
            newAssociationFnMenu.setKeepAlive("1");
            newAssociationFnMenu.setVisible("1");
            newAssociationFnMenu.setSort(0);
            newAssociationFnMenu.setType("4");

            String insertSql = MysqlUtils.genInsertSql(newAssociationFnMenu, "sys_menu");
            MysqlUtils.executeInsertSqlWithId(projectDatasource, insertSql);
        } catch (Exception e) {
            log.error("AssociationFn自动新增菜单异常", e);
        }
    }

    public static void generationControllerClass(Project project, ClassInfo classInfo) throws IOException {
        generationControllerClass(project, classInfo, true);
    }

    public static String generationControllerClass(String packageName, ClassInfo classInfo, TemplateConfig templateConfig) throws IOException {
        Project project = new Project();
        ProjectDetail backendProject = new ProjectDetail();
        backendProject.setProjectGroup(packageName);
        project.setBackendProject(backendProject);
        project.setTemplateConfig(templateConfig);
        return generationControllerClass(project, classInfo, false);
    }


    public static String generationControllerClass(Project project, ClassInfo classInfo,
                                                   boolean writeFile) throws IOException {
        String className = classInfo.getClassName();
        String classNameEntity = StringUtils.uncapitalize(className);
        String controllerName = className + "Controller";
        String projectNamePath = "";
        if (project != null) {
            projectNamePath = project.getName() + "\\";
        }
        List<String> additionCodeList = SpringbootRemoteUtil.getAdditionCode(GenSb3Vue3Util.FILE_PATH_PRE + "addition\\" + projectNamePath + "controller\\" + classNameEntity);

        Map<String, Object> params = new HashMap<>();

        params.put("packageName", project.getBackendProject().getProjectGroup());
        params.put("classInfo", JSONUtil.toJsonStr(classInfo));
        params.put("additionCodeList", JSONUtil.toJsonStr(additionCodeList));
        String mutilDatasourceStr = GenUtil.getMutilDatasourceStr(project, classInfo);
        params.put("mutilDatasourceStr", mutilDatasourceStr);
        ApiResult apiResult = RemoteUtil.getCodeFromRemote(project, "springboot/controller", params);
        Map<String, Object> data = (Map<String, Object>) apiResult.getData();
        List<String> fieldNameStrList = (List<String>) data.get("fieldNameStrList");
        if (CollectionUtil.isNotEmpty(fieldNameStrList) && project != null) {
            List<FieldName> fieldNameList = classInfo.getFieldNameList();
            fieldNameList = fieldNameList.stream().filter(fieldName -> fieldNameStrList.contains(fieldName.getName())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(fieldNameList)) {
                for (FieldName fieldName : fieldNameList) {
                    processAssociationFnMenu(project, classInfo, fieldName.getProjectTableFiledConfig());
                }
            }
        }
        String code = (String) data.get("code");
        if (writeFile) {
            String mutilDatasourcePathName = GenUtil.getMutilDatasourceStrByConfig(project, classInfo, "", File.separator);
            File classFile = GenUtil.newFile(project, "controller\\" + mutilDatasourcePathName, controllerName);
            RemoteUtil.writeFileToProject(code, classFile);
        }
        return code;
    }

}
